package multiplex.dataaccess.dao;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import multiplex.dataaccess.DaoException;
import multiplex.model.Filme;
import multiplex.model.Localizacao;

public class LocalizacaoDao extends AbstractDao{
	
	public Localizacao get(int id) throws DaoException {
		try{
			PreparedStatement st = getConnection().prepareStatement("SELECT * FROM Localizacao WHERE id =?");
			st.setInt(1, id);
			ResultSet rs = st.executeQuery();
			if(rs.next()){
				Localizacao localizacao = new Localizacao();
				fillLocalizacao(localizacao, rs);
				st.close();
				return localizacao;
			}
		} catch(Exception e){
			throw new DaoException(e);
		}
		return null;
	}

	public List<Localizacao> getAll() throws DaoException {
		List<Localizacao> localizacaoList = new ArrayList<Localizacao>();
		try{
			PreparedStatement st = getConnection().prepareStatement("SELECT * FROM Localizacao");
			
			ResultSet rs = st.executeQuery();
			while(rs.next()){
				Localizacao localizacao = new Localizacao();
				fillLocalizacao(localizacao, rs);
				localizacaoList.add(localizacao);
			}
			st.close();
			return localizacaoList;
		}catch(Exception e){
			throw new DaoException(e);
		}
	}
	
	public List<Localizacao> getAllFromFilme(Filme filme) throws DaoException {
		List<Localizacao> localizacaoList = new ArrayList<Localizacao>();
		try{
			PreparedStatement st = getConnection().prepareStatement(
					"SELECT DISTINCT Localizacao.id AS id, Localizacao.nome AS nome, Localizacao.cidade AS cidade, " +
					"Localizacao.lugarMarcado AS lugarMarcado FROM Localizacao, Sala, Sessao, " +
					"Filme WHERE Localizacao.id=Sala.Localizacao_id " +
					"AND Sala.id=Sessao.Sala_id AND Sessao.Filme_id=Filme.id AND " +
					"Sessao.Filme_id = ?");
			st.setInt(1, filme.getId());
			ResultSet rs = st.executeQuery();
			while(rs.next()){
				Localizacao localizacao = new Localizacao();
				fillLocalizacao(localizacao, rs);
				localizacaoList.add(localizacao);
			}
			st.close();
			return localizacaoList;
		}catch(Exception e){
			throw new DaoException(e);
		}
	}

	public void save(Localizacao localizacao) throws DaoException {
		try{
			PreparedStatement st = getConnection().prepareStatement(
					"INSERT INTO Localizacao (nome, cidade, lugarMarcado) VALUES (?,?,?)", 
					Statement.RETURN_GENERATED_KEYS);
			fillPreparatedStatement(st, localizacao);
			st.execute();
			ResultSet rs = st.getGeneratedKeys();
			rs.next();
			localizacao.setId(rs.getInt(1));
			st.close();
		}catch(Throwable e){
			throw new DaoException(e);
		}	
	}
	
	public void update(Localizacao localizacao) throws DaoException {
		try{
			PreparedStatement st = getConnection().prepareStatement(
					"UPDATE Localizacao SET nome=?, cidade=?, lugarMarcado=? WHERE id=?");
			fillPreparatedStatement(st, localizacao);
			st.setInt(4, localizacao.getId());
			st.execute();
			st.close();
		}catch(Throwable e){
			throw new DaoException(e);
		}
	}

	public void remove(Localizacao localizacao) throws DaoException {
		try{
			PreparedStatement st = getConnection().prepareStatement(
					"DELETE FROM Localizacao WHERE id=?");
			st.setInt(1, localizacao.getId());
			st.execute();
			st.close();
		}catch(Throwable e){
			throw new DaoException(e);
		}	
	}
	
	private void fillLocalizacao(Localizacao localizacao, ResultSet rs) throws SQLException {
		localizacao.setId(rs.getInt("id"));
		localizacao.setNome(rs.getString("nome"));
		localizacao.setCidade(rs.getString("cidade"));
		localizacao.setLugarMarcado(rs.getBoolean("lugarMarcado"));
	}
	
	private void fillPreparatedStatement(PreparedStatement st, Localizacao localizacao) throws SQLException {
		st.setString(1,localizacao.getNome());
		st.setString(2,localizacao.getCidade());
		st.setBoolean(3,localizacao.isLugarMarcado());
	}
	
}
